COMP3141 Software System Design and Implementation

COMP3141: Software System Design and Implementation

Term 2, 2023

Quiz 9 (Week 9)

Table of Contents

1 Phantom Types

1.1 Recognizing phantom types

1.1.1 Question 1

Consider the following type definitions.

data Day we
  = Mon | Tue | Wed | Thu | Fri
  | Sat we | Sun we

data Free
data Taken
data Locker state = Locker (Maybe Int)

data List1 a b = List1 [b]
data List2 a b = Nil | List2 b (List2 a b)

Which of the types above are phantom types?

  1. Day
  2. Free
  3. Locker
  4. List1
  5. List2

1.2 Safe Division

We can use phantom types to avoid divide-by-zero errors as follows:

data Zero
data NonZero
data CheckedInt t = Checked Int

safeDiv :: Int -> CheckedInt NonZero -> Int
safeDiv x (Checked y) = x `div` y 

1.2.1 Question 2

Which of the following statements are true?

  1. The type argument t does not occur in Checked.
  2. The types Zero and NonZero are both phantom types.
  3. This code will not compile as Zero and NonZero have not been defined.
  4. The pattern matching in safeDiv is non-exhaustive (i.e. missing cases).

1.2.2 Question 3

Which of the following could be a valid type signature for a function add that calculates the sum of any two CheckedInt values?

  1. CheckedInt NonZero -> CheckedInt NonZero -> CheckedInt NonZero
  2. CheckedInt a -> CheckedInt a -> CheckedInt a
  3. CheckedInt a -> CheckedInt b -> Int
  4. CheckedInt a -> CheckedInt b -> CheckedInt c

1.2.3 Question 4

Choose the best type to give to a smart constructor for the type CheckedInt!

  1. check :: Int -> CheckedInt NonZero
  2. check :: Int -> CheckedInt (Either Zero NonZero)
  3. check :: Int -> CheckedInt t
  4. check :: Int -> Either (CheckedInt Zero) (CheckedInt NonZero)

1.3 Data Kinds

Here we use phantom types with an argument of kind Size to make vectors of various dimensions. Note that the vector size is not statically checked by the default V data constructor. We must be sure to only use the given smart constructors that establish the length invariant about the data:

{-# LANGUAGE DataKinds #-}
{-# LANGUAGE KindSignatures #-}

data Size = OneD  | TwoD | ThreeD
newtype Vector (s :: Size) a = V [a]

vec1D :: a -> Vector OneD a
vec1D a = V [a]

vec2D :: (a, a) -> Vector TwoD a
vec2D (a,b) = V [a,b]

vec3D :: (a, a, a) -> Vector ThreeD a
vec3D (a,b,c) = V [a,b,c]

1.3.1 Question 5

Which of the following implementations of vector addition ensure via a static check that the precondition that the vectors must be the same size (and only that precondition), as well as the postcondition that the output vector will be the same size as the input?

  1. addV :: (Num n) => Vector a n -> Vector b n -> Vector c n
    addV (V xs) (V ys) = V (zipWith (+) xs ys)
    
  2. addV :: (Num n) => Vector a n -> Vector a n -> Vector a n
    addV (V xs) (V ys) = V (zipWith (+) xs ys)
    
  3. addV :: (Num n) => Vector TwoD n -> Vector TwoD n -> Vector TwoD n
    addV (V xs) (V ys) = V (zipWith (+) xs ys)
    
  4. addV :: (Num n) => Vector a n -> Vector a n -> Vector b n
    addV (V xs) (V ys) = V (zipWith (+) xs ys)
    

1.3.2 Question 6

Suppose we made a Matrix type using vectors of vectors:

type Matrix r c a = Vector r (Vector c a)

What would be a correct type for a matrix multiplication function?

  1. mm :: Num a => Matrix r i a -> Matrix r i a -> Matrix r i a
  2. mm :: Num a => Matrix r i a -> Matrix i c a -> Matrix r i a
  3. mm :: Num a => Matrix r i a -> Matrix c i a -> Matrix i i a
  4. mm :: Num a => Matrix r i a -> Matrix i c a -> Matrix r c a

1.4 Static Assurance

1.4.1 Question 7

Select all true statements below.

  1. Testing is the most common form of static analysis.
  2. You can compile and run your Haskell program even if it fails type checking.
  3. Types and model checkers are forms of static assurance.
  4. Static means of assurance can analyze programs without running them.

1.4.2 Question 8

Which of the following is ruled out by Rice's theorem?

  1. Deciding whether a program contains a while loop.
  2. Deciding whether a computable function always returns non-zero output.
  3. Deciding whether a Haskell program has type Int -> Int.
  4. Deciding whether a Haskell program has type Int -> CheckedInt NonZero.

2023-08-13 Sun 12:51

Announcements RSS